import os
import subprocess
import json
import time

from Global import MulatorInfoStruct


class MuMuMulator:
    def __init__(self, mumu_manager):
        """
        初始化MuMu模拟器管理类
        :param mumu_path: MuMuManager.exe的完整路径
        """
        if not os.path.exists(mumu_manager):
            raise FileNotFoundError(f"MuMu模拟器管理程序不存在: {mumu_manager}")

        self.mumu_manager = mumu_manager
        self.mumu_path = os.path.dirname(mumu_manager)

    def _execute_command(self, command):
        """
        执行adb命令并返回结果
        :param command: 完整的命令列表
        :return: (returncode, stdout, stderr)
        """
        try:
            process = subprocess.Popen(
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                encoding='utf-8'
            )
            stdout, stderr = process.communicate()
            return process.returncode, stdout, stderr
        except Exception as e:
            return -1, "", str(e)

    def GetMulatorInfo(self, index):
        """
        获取模拟器信息
        :param index: 模拟器序号
        :return: dict 模拟器信息字典，失败返回None
        """
        cmd = [self.mumu_manager, "info", "-v", str(index)]
        returncode, stdout, stderr = self._execute_command(cmd)
        mumu = MulatorInfoStruct()
        if returncode == 0:
            try:
                jj = json.loads(stdout)
                mumu.deviceName = jj["adb_host_ip"]+":"+str(jj["adb_port"])
                mumu.index=int(jj["index"])
                mumu.is_android_started = jj["is_android_started"]
                mumu.headless_pid = int(jj["headless_pid"])
                mumu.render_wnd = int(jj["render_wnd"], base=16)
            except json.JSONDecodeError:
                # 如果不是JSON格式，返回原始输出
                return mumu
        return mumu

    def Launch(self, index,package=None):
        """
        启动指定模拟器
        :param index: 模拟器序号
        :return: bool
        """
        if package==None:
            cmd = [self.mumu_manager, "control", "-v", str(index),"launch"]
        else:
            cmd = [self.mumu_manager, "control", "-v", str(index), "launch","-pkg",package]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def Shutdown(self, index):
        """
        停止指定模拟器
        :param index: 模拟器序号
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index),"shutdown"]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def Restart(self, index):
        """
        重启指定模拟器
        :param index: 模拟器序号
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index), "restart"]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def install_app(self, index, apk_path):
        """
        安装应用
        :param index: 模拟器序号
        :param apk_path: APK文件路径
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index), "app","install","-apk",apk_path]
        returncode, stdout, stderr = self._execute_command(cmd)
        if returncode==0:
            try:
                jj= json.loads(stdout)
            except json.JSONDecodeError:
                return False,stdout
        else:
            return False,stderr
        return True,""

    def uninstall_app(self, index, package_name):
        """
        卸载应用
        :param index: 模拟器序号
        :param package_name: 应用包名
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index),"app","uninstall","-pkg",package_name]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0
    def run_app(self, index, package_name):
        """
        卸载应用
        :param index: 模拟器序号
        :param package_name: 应用包名
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index),"app","launch","-pkg",package_name]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def stop_app(self, index, package_name):
        """
        卸载应用
        :param index: 模拟器序号
        :param package_name: 应用包名
        :return: bool
        """
        cmd = [self.mumu_manager, "control", "-v", str(index), "app", "close", "-pkg", package_name]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0


    def set_property(self, index, prop_name, value):
        """
        设置模拟器属性
        :param index: 模拟器序号
        :param prop_name: 属性名称
        :param value: 属性值
        :return: bool
        """
        cmd = [self.mumu_manager, "adb", "-v",str(index),"-c","setprop",prop_name, str(value)]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def get_property(self, index, prop_name):
        """
        获取模拟器属性
        :param index: 模拟器序号
        :param prop_name: 属性名称
        :return: 属性值，失败返回None
        """
        cmd = [self.mumu_manager, "adb", "-v",str(index),"-c","getprop",prop_name]
        returncode, stdout, stderr = self._execute_command(cmd)
        if returncode == 0:
            return stdout.strip()
        return None
    def go_back (self, index):
        """
        按下安卓返回键
        :param index: 模拟器序号
        :return:
        """
        cmd = [self.mumu_manager, "adb", "-v",str(index),"-c","go_back"]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0
    def go_home (self, index):
        """
        按下安卓返回键
        :param index: 模拟器序号
        :return:
        """
        cmd = [self.mumu_manager, "adb", "-v",str(index),"-c","go_home"]
        returncode, stdout, stderr = self._execute_command(cmd)
        return returncode == 0

    def shell(self, index,shellcmd):
        """
        执行shell命令
        :param index: 模拟器序号
        :param shellcmd: shell命令
        :return:
        """
        cmd = [self.mumu_manager, "adb", "-v", str(index), "-c", shellcmd]
        returncode, stdout, stderr = self._execute_command(cmd)
        return stdout